package org.crawutils.pickcommon;

import java.io.ObjectStreamClass;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.crawutils.IBeforOrAfterHandler;
import org.crawutils.Utils;
import org.crawutils.pickcommon.xmlvo.Convert;
import org.crawutils.pickcommon.xmlvo.Entity;
import org.crawutils.pickcommon.xmlvo.HtmlModel;
import org.crawutils.pickcommon.xmlvo.Modelchild;
import org.crawutils.pickcommon.xmlvo.ReadTemplate;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public abstract class ParseHandle implements IBeforOrAfterHandler{
	private ReadTemplate rx;
	public ParseHandle(){
		 rx=new ReadTemplate(templateXml());
		 rx.parseXml();
	}
	
	/**
	 * 对应的模版配置文件
	 * @return
	 */
	public abstract String templateXml();
	
	/**
	 * 自定义采集方法
	 */
	public abstract void parseHtml(Document doc,ReadTemplate rx,List<Entity> entityList,Map<String,Object> map) throws Exception;
	
	
	/**
	 * 字段的转换器，默认返回String
	 * @return
	 */
	public  Class<? extends Convert> convert(){
	  return StringConvert.class;	
	}
	
	
	public Map<String,Object> parseHtml(String html) throws Exception {
		Map<String,Object> map=new HashMap<String, Object>();
		List<Entity> entityList = new ArrayList<Entity>();
		
		Document doc=Jsoup.parse(html);
		List<HtmlModel> htmlModels = rx.getHtmlModels();
         for(HtmlModel htmlModel : htmlModels){
        	 Elements elements= doc.select(htmlModel.getQuerys());
        	 List<Modelchild> listMc=htmlModel.getChildren();
 			 String modelClass=htmlModel.getModelclass();
 			 Object modelObj=null;
 			 if(StringUtils.isNotBlank(modelClass)){
 				modelObj=Class.forName(modelClass).newInstance();
 			 }
 			 for(Modelchild mc:listMc){
 				Elements childEles=elements.select(mc.getQuerys());
 				String origvalue="";
 				for(Element ele:childEles){
 					if(StringUtils.isBlank(mc.getExtract())|| "text".equals(mc.getExtract())){
 	 					//默认取text
 	 					origvalue=ele.text();
 	 				}else if("html".equals(mc.getExtract())){
 	 					origvalue=ele.html();
 	 				}else if("outhtml".equals(mc.getExtract())){
 	 					origvalue=ele.outerHtml();
 	 				}else{
 	 					origvalue=ele.attr(mc.getExtract());
 	 				}
 	 				if(modelObj!=null){
 	 					Utils.callSetMethod(modelObj,mc.getText(),origvalue,origvalue.getClass());
 	 	 	 		}else{
 	 	 	 			String mctext=mc.getText();
 	 	 	 			String[] mctext_splits=mctext.split("\\.");
 	 	 	 			String beanclass=rx.getBeanMap().get(mctext_splits[0]);
 	 	 	 			if("java.util.ArrayList".equals(beanclass)){
 	 	 	 				List modellist=(ArrayList)map.get(mctext_splits[0]);
 	 	 	 				if(modellist==null){
 	 	 	 					modellist=new ArrayList<String>();
 	 	 	 					modellist.add(origvalue);
 	 	 	 					map.put(mctext_splits[0],modellist);
 	 	 	 				}else{
 	 	 	 					modellist.add(origvalue);
 	 	 	 				}
 	 	 	 				
 	 	 	 			}else if("java.util.HashMap".equals(beanclass)){
 	 	 	 				Map<String,String> modelmap=(HashMap<String, String>)map.get(mctext_splits[0]);
 	 	 	 				if(modelmap==null){
 	 	 	 					modelmap=new HashMap<String, String>();
 	 	 	 					modelmap.put(mctext_splits[1],origvalue);
 	 	 	 					map.put(mctext_splits[0],modelmap);
 	 	 	 				}else{
 	 	 	 					modelmap.put(mctext_splits[1],origvalue);
 	 	 	 				}
 	 	 	 			}else{
 	 	 	 				Entity entity = new Entity();
 	 	 	 	 			entity.setType(origvalue.getClass());
 	 						entity.setName(mctext);
 	 						entity.setValue(origvalue);
 	 						entityList.add(entity);	
 	 	 	 			}
 	 	 	 			
 	 	 			 }
 	 				
 	 				
 	 			 		
 				}
 			}
 			 if(modelObj!=null){
 				List list=(ArrayList)map.get(modelClass);
 				if(list!=null && list.size()>0){
 					list.add(modelObj);
 				}else{
 				   list=new ArrayList<Object>();
 				   list.add(modelObj);
 				   map.put(modelClass,list);
 				}
 				
 			 }
 			 
 			
         }
     
  
		parseHtml(doc, rx, entityList, map);
		Map<String, String> beanMap = rx.getBeanMap();
		Map<String, Object> objMap = new HashMap<String, Object>();
		for (Entity ent : entityList) {
			String key = ent.getName();
			String[] keys = key.split("\\.");
			Object obj = null;
			if (objMap.containsKey(keys[0])) {
				obj = objMap.get(keys[0]);
			} else {
				obj = Class.forName(beanMap.get(keys[0])).newInstance();
			}
			objMap.put(keys[0], obj);
			Utils.callSetMethod(obj, keys[1], ent.getValue(), ent.getType());

			String modelClass=obj.getClass().getName();
			 if(obj!=null){
	 				List list=(ArrayList)map.get(modelClass);
	 				if(list!=null && list.size()>0){
	 					list.add(obj);
	 				}else{
	 				   list=new ArrayList<Object>();
	 				   list.add(obj);
	 				   map.put(modelClass,list);
	 				}
	 				
	 			 }
			
		}

		return map;
	}
}
